package com.example.mybatis.aspect;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Aspect
@Component
@Order(value = 1)
public class ExpressionAspect {

    private final static Logger logger = LoggerFactory.getLogger(ExpressionAspect.class);

    private long startTime = 0;
    private long endTime = 0;
    @Before(value = "execution(* com.example.mybatis.service.*Service.*(..))")
    public void beforeAdvice(JoinPoint joinPoint){
        logger.info("进入前置通知方法....");
        Object[] args = joinPoint.getArgs();
        //打印参数
        for(int i=0;i<args.length;i++){
            if(!(args[i] instanceof HttpServletRequest)&&!(args[i] instanceof HttpServletResponse))
            logger.info("args["+i+"]={}", JSON.toJSONString(args[i], SerializerFeature.PrettyFormat));
        }
        startTime = System.currentTimeMillis();
    }

    @AfterReturning(value = "execution(* com.example.mybatis.service.*Service.*(..))",returning = "returnVal")
    public void afterReturnAdvice(JoinPoint joinPoint,Object returnVal){
        logger.info("进入后置通知方法...");
        endTime = System.currentTimeMillis();
        Signature signature = joinPoint.getSignature();
        String signatureName = signature.getName();
        logger.info("signatureName={}",signatureName);
        logger.info("{}方法执行耗时={}",signatureName,(endTime-startTime)+"ms");
        Object _this = joinPoint.getThis();
        Object target = joinPoint.getTarget();
        logger.info("_this==target:{}",_this==target);
        logger.info("_thisClassName={}",_this.getClass().getName());
        logger.info("targetClassName={}",target.getClass().getName());
        if(returnVal!=null){
            logger.info("returnValClassName={}",returnVal.getClass().getName());
            logger.info("returnVal={}",JSON.toJSONString(returnVal,SerializerFeature.PrettyFormat));
        }

    }

    @AfterThrowing(value = "execution(* com.example.mybatis.service.*Service.*(..))",throwing = "ex")
    public void afterThrowingAdvice(JoinPoint joinPoint,Exception ex){
        logger.info("进入异常通知方法...");
        Object targetObject = joinPoint.getTarget();
        Signature signature = joinPoint.getSignature();
        logger.error("exception occurred at class "+targetObject.getClass().getName()+
                "\n signatureName="+signature.getName(),ex);
        logger.info("ExceptionClassName={}",ex.getClass().getName());
        logger.info("message:{}",ex.getMessage());

    }

    @After(value = "execution(* com.example.mybatis.service.*Service.*(..))")
    public void afterAdvice(JoinPoint joinPoint){
        logger.info("进入最终后置通知方法....");
        logger.info("signatureName={}",joinPoint.getSignature().getName());
    }


}
